import Flutter
import UIKit
import AVFoundation

public class SwiftMultiShowPlugin: NSObject, FlutterPlugin {
    public static func register(with registrar: FlutterPluginRegistrar) {
        let channel = FlutterMethodChannel(name: "multi_show", binaryMessenger: registrar.messenger())
        let instance = SwiftMultiShowPlugin()
        registrar.addMethodCallDelegate(instance, channel: channel)
    }

    public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
        switch call.method {
        case "multiShow":multiShow(call, result: result)
        case "getPlatformVersion":getPlatformVersion(call, result: result)
        case "takePhoto":takePhoto(call, result: result)
        case "thumbPathForAssetVideo":getThumbPathForAssetVideo(call, result: result)
        case "thumbPathForNetworkVideo":getThumbPathForNetworkVideo(call, result: result)
        default:
            break
        }
    }
    
    /// 图片视频显示
    /// - Parameters:
    ///   - call:
    ///   - result: void
    private func multiShow(_ call: FlutterMethodCall, result: @escaping FlutterResult){
        guard let vc = UIApplication.shared.keyWindow?.rootViewController else {
            result(["success":false,"error":"not view controller"])
            return
        }
        guard let arguments = call.arguments as? [String:Any] else {
            result(["success":false,"error":"arguments is empty"])
            return
        }
        let currentIndex = arguments["currentIndex"] as? Int ?? 0
        let paths = arguments["paths"] as? [Any] ?? []
        var assetPaths:[[String:Any]] = []
        for path in paths {
            var pathMap:[String:Any] = [:]
            switch path {
            case is String:
                let tempPath = path as! String
                pathMap["path"] = tempPath
                if tempPath.isVideoPath() {
                    pathMap["type"] = "video"
                }else {
                    pathMap["type"] = "image"
                }
                assetPaths.append(pathMap)
            case is [String:Any]:
                let pathDict = path as! [String:Any]
                pathMap["path"] = pathDict["url"] ?? ""
                pathMap["title"] = pathDict["title"] ?? ""
                if (pathMap["path"] as! String).isVideoPath() {
                    pathMap["type"] = "video"
                }else {
                    pathMap["type"] = "image"
                }
                assetPaths.append(pathMap)
            default:continue
            }
        }
        if assetPaths.count <= 0 {
            result(["success":false,"error":"paths is empty"])
            return
        }
        CXShowAssetsManager.sharedInstance().show(controller: vc, assetPaths: assetPaths, currentIndex: currentIndex)
        result(["success":true,"error":""])
    }
    private func getPlatformVersion(_ call: FlutterMethodCall, result: @escaping FlutterResult){
        result("iOS " + UIDevice.current.systemVersion)
    }
    
    
    /// 获取图片
    /// - Parameters:
    ///   - call:
    ///   Map<
    ///         maxCoshount:Int,// 数量 最大选择数
    ///         selectType:Int,// 选择类型 1: 图片  2: 视频+图片 3: 视频
    ///   >
    ///   - result:
    ///   Map<
    ///     success:bool,// 操作成功/失败
    ///     paths:List<String>,// 图片路径列表
    ///     error:String, // 错误信息
    ///    >
    private func takePhoto(_ call: FlutterMethodCall, result: @escaping FlutterResult){
        guard let vc = UIApplication.shared.keyWindow?.rootViewController else {
            result(["success":false,"paths":[],"error":"not view controller"])
            return
        }
        guard let arguments = call.arguments as? [String:Any] else {
            result(["success":false,"paths":[],"error":"arguments is empty"])
            return
        }
        guard   let maxCoshount = arguments["maxCoshount"] as? Int,
                let selectType = arguments["selectType"] as? Int,
                maxCoshount >= 1,(selectType >= 1 && selectType <= 3) else {
            result(["success":false,"paths":[],"error":"arguments is error"])
            return
        }
        DispatchQueue.main.async {
            CXSelectAssetManager
                .sharedInstance()
                .selectPhotoPaths(
                    dataSource: vc,
                    maximum: maxCoshount,
                    selectType: selectType,
                    haveNb: 0) { (imagePaths) in
                        var tempImagePaths:[String] = []
                        for path in imagePaths {
                            if path.isEmpty {
                                continue
                            }
                            tempImagePaths.append(path)
                        }
                        result(["success":true,"paths":tempImagePaths,"error":""])
            }
        }
    }
    
    private func getThumbPathForAssetVideo(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
        guard let arguments = call.arguments as? [String:Any] else {
            result(["success":false,"path":"","error":"视频地址不存在"])
            return
        }
        guard let videoPath = arguments["videoPath"] as? String else {
            result(["success":false,"path":"","error":"视频地址不存在"])
            return
        }
        let pathUrl = URL(fileURLWithPath: videoPath)
        let videoAsset = AVURLAsset(url: pathUrl)
        let assetGen = AVAssetImageGenerator(asset: videoAsset)
        let time = CMTimeMakeWithSeconds(0, preferredTimescale: 600)
        var actualTime:CMTime = CMTimeMake(value: 0, timescale: 0)
        do {
            let imageRef = try assetGen.copyCGImage(at: time, actualTime: &actualTime)
            let thumbImage:UIImage = UIImage(cgImage: imageRef)
            thumbImage.saveImage { (path, error) in
                if path == nil {
                    result(["success":false,"path":"","error":"获取视频预览图失败"])
                    return
                }
                result(["success":true,"path":path!,"error":"获取视频预览图失败"])
                return
            }
        } catch {
            result(["success":false,"path":"","error":"获取视频预览图失败"])
            return
        }
    }
    
    private func getThumbPathForNetworkVideo(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
        guard let arguments = call.arguments as? [String:Any] else {
            result(["success":false,"path":"","error":"视频地址不存在"])
            return
        }
        guard let videoPath = arguments["videoPath"] as? String else {
            result(["success":false,"path":"","error":"视频地址不存在"])
            return
        }
        guard let pathUrl = URL(string: videoPath) else {
            result(["success":false,"path":"","error":"视频地址不正确"])
            return
        }
        let videoAsset = AVURLAsset(url: pathUrl)
        let assetGen = AVAssetImageGenerator(asset: videoAsset)
        let time = CMTimeMakeWithSeconds(0, preferredTimescale: 600)
        var actualTime:CMTime = CMTimeMake(value: 0, timescale: 0)
        do {
            let imageRef = try assetGen.copyCGImage(at: time, actualTime: &actualTime)
            let thumbImage:UIImage = UIImage(cgImage: imageRef)
            thumbImage.saveImage { (path, error) in
                if path == nil {
                    result(["success":false,"path":"","error":"获取视频预览图失败"])
                    return
                }
                result(["success":true,"path":path!,"error":"获取视频预览图失败"])
                return
            }
        } catch {
            result(["success":false,"path":"","error":"获取视频预览图失败"])
            return
        }
    }
}
